<template>
  <div v-if="showScrollControls" class="floating-scroll-panel" :class="{ 'expanded': isScrollPanelExpanded }">
    <!-- 收起状态的小标签 -->
    <div v-if="!isScrollPanelExpanded" class="scroll-panel-collapsed" @click="isScrollPanelExpanded = true">
      <el-icon class="expand-icon">
        <Operation />
      </el-icon>
      <span class="collapsed-text">滚动</span>
    </div>

    <!-- 展开状态的完整面板 -->
    <div v-if="isScrollPanelExpanded" class="scroll-panel-expanded">
      <div class="scroll-panel-header">
        <span class="panel-title">表格滚动控制</span>
        <el-button type="text" size="small" icon="Fold" @click="isScrollPanelExpanded = false"
          class="collapse-btn" title="收起面板"></el-button>
      </div>

      <div class="scroll-bar-container">
        <div class="custom-scroll-bar" @click="handleScrollBarClick" ref="customScrollBarRef">
          <div class="scroll-thumb" :style="{ left: scrollThumbPosition }" @mousedown="startDrag"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup name="TableScrollControl" lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';

interface Props {
  tableRef?: any; // 表格引用
  visible?: boolean; // 是否显示控制面板
  position?: {
    top?: string;
    right?: string;
    bottom?: string;
    left?: string;
  }; // 面板位置
}

const props = withDefaults(defineProps<Props>(), {
  visible: true,
  position: () => ({ top: '30%', right: '20px' })
});

// 响应式变量
const customScrollBarRef = ref<HTMLDivElement>();
const showScrollControls = ref(props.visible);
const isScrollPanelExpanded = ref(false);
const needScrollControl = ref(false);
const scrollThumbPosition = ref('0%');
const isDragging = ref(false);

// 获取Element UI表格的滚动容器
const getTableBodyEl = () => {
  if (!props.tableRef) return null;
  
  const tableEl = props.tableRef.$el;
  if (!tableEl) return null;
  
  // Element UI表格的常见滚动容器选择器（按优先级排序）
  const selectors = [
    '.el-table__body-wrapper',
    '.el-scrollbar__wrap',
    '.el-table__body',
    '.el-scrollbar__view',
    '.el-table .el-scrollbar .el-scrollbar__wrap',
  ];
  
  // 逐个尝试选择器
  for (const selector of selectors) {
    const tableBodyEl = tableEl.querySelector(selector);
    if (tableBodyEl && tableBodyEl.scrollWidth > tableBodyEl.clientWidth) {
      return tableBodyEl;
    }
  }
  
  // 深度搜索可滚动元素
  const allElements = tableEl.querySelectorAll('*');
  for (const el of allElements) {
    const element = el as HTMLElement;
    if (element.scrollWidth > element.clientWidth && 
        element.scrollWidth > 0 && 
        element.clientWidth > 0) {
      return element;
    }
  }
  
  return null;
};

const updateScrollState = () => {
  const tableBodyEl = getTableBodyEl();
  if (!tableBodyEl) return;

  const scrollWidth = tableBodyEl.scrollWidth;
  const clientWidth = tableBodyEl.clientWidth;
  const scrollLeft = tableBodyEl.scrollLeft;

  // 检查是否需要滚动控制
  needScrollControl.value = scrollWidth > clientWidth;

  if (needScrollControl.value) {
    const maxScroll = scrollWidth - clientWidth;
    // 更新滚动条拖拽块位置
    scrollThumbPosition.value = `${(scrollLeft / maxScroll) * 80}%`;
  }
};

const handleScrollBarClick = (event: MouseEvent) => {
  if (!customScrollBarRef.value) return;
  
  const rect = customScrollBarRef.value.getBoundingClientRect();
  const clickX = event.clientX - rect.left;
  const percentage = Math.max(0, Math.min(1, clickX / rect.width));
  
  const tableBodyEl = getTableBodyEl();
  if (!tableBodyEl) return;
  
  const maxScroll = tableBodyEl.scrollWidth - tableBodyEl.clientWidth;
  const targetScrollLeft = maxScroll * percentage;
  
  tableBodyEl.scrollLeft = targetScrollLeft;
  tableBodyEl.dispatchEvent(new Event('scroll', { bubbles: true }));
  
  // 备用滚动方法
  setTimeout(() => {
    if (Math.abs(tableBodyEl.scrollLeft - targetScrollLeft) >= 5) {
      if (tableBodyEl.scrollTo) {
        tableBodyEl.scrollTo({ left: targetScrollLeft, behavior: 'smooth' });
      }
      
      let parent = tableBodyEl.parentElement;
      while (parent) {
        if (parent.scrollWidth > parent.clientWidth) {
          parent.scrollLeft = targetScrollLeft;
          break;
        }
        parent = parent.parentElement;
      }
    }
  }, 50);
  
  updateScrollState();
};

const startDrag = (event: MouseEvent) => {
  isDragging.value = true;
  event.preventDefault();
  
  const handleMouseMove = (e: MouseEvent) => {
    if (!isDragging.value || !customScrollBarRef.value) return;
    
    const rect = customScrollBarRef.value.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const percentage = Math.max(0, Math.min(1, x / rect.width));
    
    const tableBodyEl = getTableBodyEl();
    if (!tableBodyEl) return;
    
    const maxScroll = tableBodyEl.scrollWidth - tableBodyEl.clientWidth;
    const targetScrollLeft = maxScroll * percentage;
    
    tableBodyEl.scrollLeft = targetScrollLeft;
    tableBodyEl.dispatchEvent(new Event('scroll', { bubbles: true }));
    
    updateScrollState();
  };
  
  const handleMouseUp = () => {
    isDragging.value = false;
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);
  };
  
  document.addEventListener('mousemove', handleMouseMove);
  document.addEventListener('mouseup', handleMouseUp);
};

const setupScrollListener = () => {
  const tableBodyEl = getTableBodyEl();
  if (!tableBodyEl) return;

  tableBodyEl.addEventListener('scroll', updateScrollState);
  window.addEventListener('resize', updateScrollState);
};

const removeScrollListener = () => {
  const tableBodyEl = getTableBodyEl();
  if (tableBodyEl) {
    tableBodyEl.removeEventListener('scroll', updateScrollState);
  }
  window.removeEventListener('resize', updateScrollState);
};

// 初始化滚动控制
const initScrollControl = () => {
  nextTick(() => {
    setupScrollListener();
    updateScrollState();
    
    // 延迟再次尝试，确保表格完全渲染
    setTimeout(() => {
      setupScrollListener();
      updateScrollState();
    }, 1000);
  });
};

// 暴露方法给父组件
defineExpose({
  initScrollControl,
  updateScrollState,
  setupScrollListener,
  removeScrollListener
});

// 监听props变化
watch(() => props.visible, (newVal) => {
  showScrollControls.value = newVal;
});

watch(() => props.tableRef, () => {
  if (props.tableRef) {
    initScrollControl();
  }
}, { immediate: true });

onMounted(() => {
  if (props.tableRef) {
    initScrollControl();
  }
});

onBeforeUnmount(() => {
  removeScrollListener();
});
</script>

<style lang="scss" scoped>
/* 浮动滚动控制面板样式 */
.floating-scroll-panel {
  position: fixed;
  top: v-bind('props.position.top || "30%"');
  right: v-bind('props.position.right || "20px"');
  bottom: v-bind('props.position.bottom');
  left: v-bind('props.position.left');
  transform: translateY(-50%);
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  user-select: none;
  transition: all 0.3s ease;
}

/* 收起状态样式 */
.scroll-panel-collapsed {
  width: 50px;
  height: 50px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 8px;
  transition: all 0.3s ease;
  border-radius: 8px;
}

.scroll-panel-collapsed:hover {
  background: #f5f7fa;
  transform: scale(1.05);
}

.expand-icon {
  font-size: 16px;
  color: #409eff;
  margin-bottom: 2px;
}

.collapsed-text {
  font-size: 10px;
  color: #606266;
  font-weight: 500;
}

/* 展开状态样式 */
.scroll-panel-expanded {
  width: 120px;
  padding: 12px;
}

.scroll-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.panel-title {
  font-size: 12px;
  font-weight: 500;
  color: #606266;
}

.collapse-btn {
  padding: 0;
  width: 18px;
  height: 18px;
  min-height: 18px;
  color: #909399;
}

.collapse-btn:hover {
  color: #409eff;
}

.scroll-bar-container {
  height: 20px;
  position: relative;
  margin-top: 8px;
}

.custom-scroll-bar {
  width: 100%;
  height: 6px;
  background: #f5f7fa;
  border-radius: 3px;
  position: relative;
  cursor: pointer;
  margin-top: 7px;
  border: 1px solid #e4e7ed;
}

.scroll-thumb {
  position: absolute;
  top: 0;
  height: 6px;
  width: 20%;
  background: #409eff;
  border-radius: 3px;
  cursor: grab;
  transition: background-color 0.3s ease;
}

.scroll-thumb:hover {
  background: #337ecc;
}

.scroll-thumb:active {
  cursor: grabbing;
  background: #2d6ac7;
}
</style>
